home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / timer11.zip / ULZTIMER.C < prev    next >
C/C++ Source or Header  |  1992-04-21  |  3KB  |  102 lines

  1. /****************************************************************************
  2. *
  3. *                          Ultra Long Period Timer
  4. *
  5. *                    Copyright (C) 1992 Kendall Bennett.
  6. *                            All rights reserved.
  7. *
  8. * Filename:        $RCSfile: ulztimer.c $
  9. * Version:        $Revision: 1.3 $
  10. *
  11. * Language:        ANSI C
  12. * Environment:    any
  13. *
  14. * Description:    Module to interface to the BIOS Timer Tick for timing
  15. *                code that takes up to 24 hours (ray tracing etc). There
  16. *                is a small overhead in calculating the time, this
  17. *                will be negligible for such long periods of time.
  18. *
  19. * $Id: ulztimer.c 1.3 92/04/21 01:47:37 kjb release $
  20. *
  21. * Revision History:
  22. * -----------------
  23. *
  24. * $Log:    ulztimer.c $
  25. * Revision 1.3  92/04/21  01:47:37  kjb
  26. * Fixed bug in ULZElapsedTime().
  27. * Revision 1.2  92/04/21  01:19:36  kjb
  28. * Converted to memory model dependant library.
  29. * Revision 1.1  92/04/20  17:34:35  kjb
  30. * Initial revision
  31. ****************************************************************************/
  32.  
  33. #include "ztimer.h"
  34.  
  35. /* Macro to obtain the current timer tick value */
  36.  
  37. #define peekul(__segment,__offset) (*((ulong  far*)FP(__segment, __offset)))
  38. #define    readticks()    peekul(0x40,0x6C)
  39.  
  40. /* Macros to enable and disable interrupts. These work under Borland C++
  41.  * but will probably need to be modified for other compilers.
  42.  */
  43.  
  44. #define disable( ) __emit__( (char )( 0xfa ) )
  45. #define enable( )  __emit__( (char )( 0xfb ) )
  46.  
  47. PUBLIC ulong ULZReadTime(void)
  48. /****************************************************************************
  49. *
  50. * Function:        ULZReadTime
  51. * Returns:        Current timer tick count.
  52. *
  53. * Description:    We turn of interrupts while we
  54. *                get the value from the BIOS data area since it is stored
  55. *                as two bytes and an interrupt COULD stuff up our reading.
  56. *
  57. ****************************************************************************/
  58. {
  59.     ulong    ticks;
  60.  
  61.     disable();                /* Turn of interrupts                 */
  62.     ticks = readticks();    /* Read the BIOS timer tick value    */
  63.     enable();                /* Turn on interrupts again         */
  64.  
  65.     return ticks;
  66. }
  67.  
  68. PUBLIC ulong ULZElapsedTime(ulong start,ulong finish)
  69. /****************************************************************************
  70. *
  71. * Function:        ULZElapsedTime
  72. * Parameters:    start    - Starting timer tick value
  73. *                finish    - Ending timer tick value
  74. *
  75. * Returns:        Elapsed timer between starting time and ending time in
  76. *                1/10 ths of a second.
  77. *
  78. ****************************************************************************/
  79. {
  80.     /* Check to see whether a midnight boundary has passed, and if so
  81.      * adjust the finish time to account for this. We cannot detect if
  82.      * more that one midnight boundary has passed, so if this happens
  83.      * we will be generating erronouse results.
  84.      */
  85.  
  86.     if (finish < start)
  87.         finish += 1573040L;            /* Number of ticks in 24 hours        */
  88.  
  89.     finish -= start;
  90.  
  91.     /* Convert to 1/10ths of a second. We dont have enough precision in
  92.      * an unsigned long to convert the value accurately, so we must
  93.      * do the conversion in floating point. I prefer the answer as an
  94.      * unsigned long so it is returned that way rather than as a double.
  95.      */
  96.  
  97.     return (finish / ((double)119318.0 / 65536.0));
  98. }
  99.